#include "stdafx.h"

#include "Weapon.h"
#include "state/RunningState.h"
#include "player/PlayerContainer.h"
#include "obj/ObjContainer.h"
#include "player/Player.h"
#include "graphics/ParticleSystem.h"

/*
================================================
CannonBall class 
================================================
*/

void CannonBall::update(float dt) {
	
	lifeTime += dt;
	//glm::vec3 dir = target->m_pos - m_pos;
	//glm::vec3 dirN = glm::normalize(dir);
	//glm::vec3 desiredV = dirN * glm::length(v);
	//glm::vec3 steeringForce = desiredV;// - p.v; 
	//steeringForce = glm::normalize(steeringForce);
	//steeringForce *= 10.8f;

	v.y -= GRAVITY * dt;
#if 0
	if (p.lifeTime > 1.0f)
		p.v += steeringForce * dt;
	else 
		p.v.y += 25.0f * dt;
#endif 
	m_pos += v * dt;
	particleCounter += dt * particleRate;
}

void CannonBall::draw(bool picking) {
	
	if (picking) 
		return; // no picking supported 

	/*Game::getInstance()->boxRenderer->draw(m_pos, glm::vec3(0.1f, 0.1f, 0.1f), glm::vec4(1.0f, 0.0f, 0.3f, 1.0f));*/

	if (particleCounter > 1.0f) {
		std::vector<glm::vec4> colors;
		colors.push_back(glm::vec4(1.0f, 0.0f, 0.0f, 0.4f));
		colors.push_back(glm::vec4(1.0f, 1.0f, 1.0f, 0.4f));
		int nAddParticles = static_cast<int>(particleCounter);
		Game::getInstance()->particleSystem->AddParticles(nAddParticles, 0.2f, ParticleSystem::inout_quadratic, m_pos, 0.0f, 0.7f, v, 3.0f, colors);
		colors.clear();
		colors.push_back(glm::vec4(1.0f, 1.0f, 1.0f, 0.085f));
		Game::getInstance()->particleSystem->AddParticles(nAddParticles, 1.2f, ParticleSystem::inout_quadratic, m_pos, 0.0f, 0.7f, v*0.5f, 2.0f, colors);
		particleCounter -= static_cast<float>(nAddParticles);
	}
	//Game::getInstance()->particleSystem->AddParticles(2, 2.2f, ParticleSystem::inout_quadratic, m_pos, 0.0f, 0.7f, v*0.0f, 0.15f, colors);
	//Game::getInstance()->particleSystem->AddParticles(2, 2.3f, ParticleSystem::inout_quadratic, m_pos, 0.0f, 1.5f, v*0.0f, 0.0f, colors);
}

CollGeom* CannonBall::getCollGeom() {
	sphereGeom.pos = m_pos;
	return &sphereGeom; 
}

void CannonBall::handleColl(Obj* other) {
	other->handleColl(this);
}
void CannonBall::handleColl(PlayerObj* other) {

	other->attackMe(20.0f);

	Game::getInstance()->particleSystem->BlueExplosion(m_pos, 1.0f);
	toBeDeleted = true;
}
void CannonBall::handleColl(CannonBall* other) {
	Game::getInstance()->particleSystem->BlueExplosion(m_pos, 1.0f);
	toBeDeleted = true;
	other->toBeDeleted = true;
}
void CannonBall::handleColl(Terrain* other) {
	Game::getInstance()->particleSystem->BlueExplosion(m_pos, 1.0f);
	toBeDeleted = true;
}

/*
================================================
Weapon class 
================================================
*/

Weapon::Weapon(Player* owner, const glm::vec3& pos, const glm::vec3& relPos, const glm::vec3 & dim) :  
	owner(owner), Obj(pos), relPos(relPos), reloadTime(3.0f), reload(reloadTime), radius(50.0f), target(nullptr), dim(dim) 
{
	type = type_weapon;
}

void Weapon::update(float dt) {

	reload -= dt;
	if (reload <= 0.0f) {
#if 0 
		if (!target || glm::length(target->m_pos - m_pos) > radius) { // need to find new target
#if 0
			target = nullptr;
			std::vector<Player*> playerList = Game::getInstance()->getRunningState()->playerContainer->getEnemyPlayers(owner);
			for ( unsigned int i = 0; i < playerList.size(); ++i) {
				target = playerList[i]->army->getClosesTarget(m_pos, radius);
				if (target)
					break;
			}
#else 
			
#endif 
		}
#endif 
		target = ObjContainer::getInstance()->getClosestPlayerObj(owner, m_pos, radius);
		if (target) { // check that there is a target in range
			glm::vec2 dir = target->getPos2() - glm::vec2(m_pos.x, m_pos.z);
			dir *= ( 1.0f + randNormNegPos()*0.1f ); // avoid perfect aim 
			glm::vec2 dirN = glm::normalize(dir);
			float dirLen = glm::length(dir);
			dirLen *= ( 1.0f + randNormNegPos()*0.1f ); // avoid perfect aim 
			// assuming 45 deg angle 
			/*float vMagn = sqrt(dirLen*GRAVITY);*/
			float angle = PI / 6;
			float vMagn = sqrt( (dirLen*GRAVITY)/sin(2*angle) );

			float projRadius = 0.2f;
			
			CannonBall* p = new CannonBall(m_pos + glm::vec3(0.0f, projRadius*3.5f, 0.0f), vMagn * glm::normalize(glm::vec3(dirN.x, tan(angle), dirN.y)), projRadius, target);
			/*projectiles.push_back(p);*/
			reload = reloadTime;
		}
	}
}

void Weapon::draw(bool picking) {
	if (picking) 
		return; // TODO impl picking here 

	// draw weapon plus any projectiles 

	BoxPrimitive* boxRenderer		= Game::getInstance()->boxRenderer;
	ParticleSystem* particleSystem	= Game::getInstance()->particleSystem;

	boxRenderer->draw(m_pos + glm::vec3(0.0f, 0.5f*dim.y, 0.0f), dim, glm::vec4(0.7f, 0.3f, 0.6f, 1.0f));
}

void Weapon::move(const glm::vec3& pos) {
	m_pos = pos + relPos;
}

CollGeom* Weapon::getCollGeom() {
	return nullptr;
}


